#ifndef PROTOTYPE_H
#define PROTOTYPE_H

#include <iostream>

class Door {
public:
  Door(int id_1, int id_2) : wall_id_1_(id_1), wall_id_2_(id_2) {}
  virtual Door* Clone() {}
  int GetId1() {
    return wall_id_1_;
  }
  int GetId2() {
    return wall_id_2_;
  }

private:
  int wall_id_1_;
  int wall_id_2_;
};

class Wall {
public:
  Wall(int id) : id_(id) {}
  virtual Wall* Clone() {}
  int GetId() {
    return id_;
  }
private:
  int id_;
};

class BombedDoor : public Door {
public :
  BombedDoor(int id_1, int id_2) : Door(id_1, id_2) {
    std::cout << "BombedDoor : " << id_1 << " -> " << id_2 << std::endl;
  }
  Door* Clone() {
    return new BombedDoor(GetId1(), GetId2());
  }
};

class CastleDoor : public Door {
public :
  CastleDoor(int id_1, int id_2) : Door(id_1, id_2) {
    std::cout << "CastleDoor : " << id_1 << " -> " << id_2 << std::endl;
  }
  Door* Clone() {
    return new CastleDoor(GetId1(), GetId2());
  }
};

class BombedWall : public Wall {
public:
  BombedWall(int id) : Wall(id) {
    std::cout << "BombedWall : " << id << std::endl;
  }
  Wall* Clone() {
    return new BombedWall(GetId());
  }
};

class CastleWall : public Wall {
public:
  CastleWall(int id) : Wall(id) {
    std::cout << "CastleWall : " << id << std::endl;
  }
  Wall* Clone() {
    return new CastleWall(GetId());
  }
};

class Factory {
public:
  virtual Wall* CreateWall() = 0;
  virtual Door* CreateDoor() = 0;
};

class ProtoTypeFactory : public Factory {
public:
  ProtoTypeFactory(Wall* wall, Door* door) : wall_(wall), door_(door) {}
  Wall* CreateWall() {
    return wall_->Clone();
  }
  Door* CreateDoor() {
    return door_->Clone();
  }
private:
  Wall* wall_;
  Door* door_;
};

#endif // PROTOTYPE_H
